#!/usr/bin/perl -w
use strict;
use Getopt::Long;

#88888888888888888888888888888888888888888888888888888888888888888888888888888888

#	Usage

#88888888888888888888888888888888888888888888888888888888888888888888888888888888

my $usage = <<'USAGE';

USAGE:

    count_duplicates.pl
                [--numeric_sort]
				[--help]
				[--by_regex "(^\d+)"]
	
	removes duplicates, optionally sorting
	Prints to STDOUT
USAGE


#88888888888888888888888888888888888888888888888888888888888888888888888888888888888888888

#	Get options

#88888888888888888888888888888888888888888888888888888888888888888888888888888888888888888
# mandatory

# optional parameters
my $help;
my $numeric_sort;
my $by_regex;
GetOptions(
			'numeric_sort'			=> \$numeric_sort,
			'by_regex=s'			=> \$by_regex,
			'help'					=> \$help);

die $usage if ($help);

sub rnd_to_num($$)
{
	my ($num, $rnd_to) = @_;
	return (int(($num - 1) / $rnd_to)+1) * $rnd_to;
}

	
	# read all lines and remove "\n"
	my @arr = <>;
	chomp @arr;

	# uniquify by the whole line unless specified
	$by_regex = '(.*)' unless (defined $by_regex);
	
	# reverse so that first occurences take precedence
	@arr = reverse @arr;


	my %hash;
	my ($cnt_no_regex_matches, $cnt_empty);
	for (@arr)
	{
		$cnt_empty++, next if $_ eq '';
		$cnt_no_regex_matches++, next unless m/$by_regex/;
		$hash{$1}++;
	}
	
	# warn if some items did not match the regex
	print STDERR	"Warning:\n\t",
					$cnt_no_regex_matches,
					"\t items did not match the supplied regular expression.\n"
					if ($cnt_no_regex_matches);
	print STDERR	"Warning:\n\t",
					$cnt_empty,
					"\tempty lines were found.\n"
					if ($cnt_empty);
	
	# calculate totals
	my $total;
	$total += $hash{$_} for (keys %hash);
	
	my $longest_name = 0;
	for (keys %hash)
	{
		$longest_name = $longest_name < length($_) ?  length($_) : $longest_name;
	}
	$longest_name = $longest_name < 5 ?  5 : $longest_name;
	$longest_name = rnd_to_num($longest_name, 8) + 4;
	
	my $longest_value =0;
	for (keys %hash)
	{
		$longest_value = $longest_value < length($hash{$_}) ?  length($hash{$_}) : $longest_value;
	}
	$longest_value = $longest_value < length($total) ?  length($total) : $longest_value;
	$longest_value = rnd_to_num($longest_value, 8) + 4;
	
	if ($numeric_sort)
	{
		for (sort{$a <=> $b} keys %hash)
		{
			my $pad1	= $longest_name - length($_);
			my $pad2	= $longest_value - length($hash{$_});
			print "\t$_", ' ' x $pad1, ":",
						' ' x $pad2, "$hash{$_}\n";
		}
	}
	else
	{
		for (sort keys %hash)
		{
			my $pad1	= $longest_name - length($_);
			my $pad2	= $longest_value - length($hash{$_});
			print "\t$_", ' ' x $pad1, ":",
						' ' x $pad2, "$hash{$_}\n";
		}
	}

my $pad1	= $longest_name - length('total');
my $pad2	= $longest_value - length($total);
print "\t", '-' x ($longest_name - 4), "     :    ",
			'-' x ($longest_value - 4), "\n";

print "\tTotal", ' ' x $pad1, ":",
			' ' x $pad2, "$total\n";
